import configparser
import sys
import os
current_file_path = os.path.abspath(__file__)
factory_root_parent_dir = os.path.dirname(os.path.dirname(current_file_path))
sys.path.insert(0, factory_root_parent_dir)

from flask import Flask, request, jsonify
from flask_socketio import SocketIO, emit
import threading
from flask_cors import CORS  # 允许跨域
from utils.randomUtils import generate_random_string
from managers.userManager import UserManager, ProjectManager
from db.userDBManager import UserDBManager
from functools import wraps
from managers.project import Project
import agentscope 
config = configparser.ConfigParser()
config.read('config.ini')
openai_api_key = config['Global']['api_key']
OPENAI_CFG_DICT = {
    "config_name": "openai_cfg",    # 此配置的名称，必须保证唯一
    "model_type": "openai_chat",         # 模型类型
    "model_name": config['Global']['model'],  # 模型名称
    "api_key": openai_api_key,      # OpenAI API key. 如果没有设置，将使用环境变量中的 OPENAI_API_KEY

    "client_args": {
        "base_url": config['Global']['base_chat_url']
    },
}
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")

# 创建主 Flask 应用
app = Flask(__name__)
socketio = SocketIO(app)
userDBManager = UserDBManager()
userManager = UserManager(userDBManager)
projectManager = ProjectManager(app)


CORS(app, resources={r"/api/*": {"origins": "*"}, r"/socket.io/*": {"origins": "*"}})

# 启动 Flask 服务和 SocketIO 实例
def start_socketio_instance(port, socketio):
    socketio.run(app, port=port)

@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    userID = userDBManager.login(data['username'], data['password'])
    if userID is not None:
        if (userManager.getUser(userID)is None):
            userManager.addUser( userID )
        u = userDBManager.get_user_login_info(userID)
        return {'success':True, 'userID':userID, 'username':u['username'], 'message': 'Login successful'}
    else:
        return {'success':False, 'userID':None, 'username':None, 'message': 'Login failed'}

@app.route('/api/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    user_email = data.get('user_email')
    user_password = data.get('user_password')
    userID = userDBManager.register(username, user_email, user_password)
    if userID is not None:
        return {'success':True,'userID':userID,'username':username, 'message': 'Registration successful'}
    else:
        return {'success':False, 'userID':None, 'username':None, 'message': 'Registration failed'}

def require_user(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        data = request.get_json()
        if not data:
            return jsonify({'success': False, 'message': 'No JSON data provided'}), 400
        
        user_id = data.get('userID')
        if not user_id:
            return jsonify({'success': False, 'message': 'userID is required'}), 400
            
        user = userManager.getUser(user_id)
        if user is None:
            return jsonify({'success': False, 'message': 'User not logged in'}), 401
            
        # 将用户对象添加到 kwargs 中，这样路由处理函数可以直接使用
        kwargs['user'] = user
        return f(*args, **kwargs)
    return decorated_function

@app.route('/api/checkProjectRunning', methods=['POST'])
@require_user
def checkProjectRunning(user):
    data = request.get_json()
    project_id = data.get('projectID')
    if project_id not in user.getRunningProjects().keys():
        return {'success': True, 'running': False}
    return {'success': True, 'running': True}

@app.route('/api/fetchUserEditingProjects', methods=['POST'])
@require_user
def fetchUserEditingProjects(user):
    projects = user.getEditingProjects()
    return_code = [{'projectID': k, **v} for k, v in projects.items()]
    print(return_code)
    return jsonify({'success': True, 'projects': return_code})

@app.route('/api/saveUserProject', methods=['POST'])
@require_user
def saveUserProject(user):
    data = request.json
    project_id = data.get('projectID')
    project_content = data.get('content')
    user.saveUserProject(project_id, project_content)
    return {'success': True, 'message': 'Project saved'}

@app.route('/api/getUserRunningProjects', methods=['POST'])
@require_user
def getUserRunningProjects(user):
    projects = user.getRunningProjects()
    return_code = []
    for projectk, projectv in projects.items():
        return_code.append({
            'user_id': user.user_id,
            'username': user.user_info['username'],
            'project_id': projectk,
            'project_name': projectv.project_name,
            'full_url': projectv.graphNodeManager.http_node.full_url,
        })
        break
    return {'data': return_code}

@app.route('/api/getAvailableRoutes', methods=['POST'])
def getAvailableRoutes():
    data = request.json
    project_token = data.get('project_token')
    if project_token not in Project._project_token_to_project:
        return {'success': False, 'routes': []}
    project = Project._project_token_to_project[project_token]
    messageRoutes = []  
    audioRoutes = []
    for k, v in project.onlineRoutes.items():
        if v[0] == 'message':
            messageRoutes.append({'value':k, 'node_name':v[1], 'user_id':project.user.user_id, 'project_id':project.id})
        elif v[0] == 'audio':
            audioRoutes.append({'value':k, 'node_name':v[1], 'user_id':project.user.user_id, 'project_id':project.id})
    return {'success': True,'data': {'messageRoutes': messageRoutes, 'audioRoutes': audioRoutes}}

# 创建一个动态 WebSocket 路由
@app.route('/api/createWS', methods=['POST'])
@require_user
def create_websocket(user):
    data = request.json
    project_id = data.get('currentProject')
    user.stopProject(project_id)
    p = user.getEditingProject(project_id)
    user.deployProject(
        project_id, 
        p['projectName'],   
        p['content']
    )
    return {'success': True, 'message': 'Created!'}, 200



# 启动 Flask 服务
if __name__ == '__main__':
    socketio.run(app, debug=True, port=5000)